package sqlite

import (
	"database/sql"
	"fmt"
	"lark/src/object"

	_ "github.com/mattn/go-sqlite3"
)

// 数据库连接对象
type Database struct {
	DB *sql.DB
}

// 结果集对象
type ResultSet struct {
	Rows    *sql.Rows
	Columns []string
}

func NewDatabase() *Database {
	return &Database{}
}

// 连接数据库函数
func (db *Database) connectDB(args ...object.Object) object.Object {

	path, ok := args[0].(*object.String)
	if !ok {
		// return object.NewError("argument to get() must be a string")
	}

	newDB, err := sql.Open("sqlite3", path.Value)
	if err != nil {
		fmt.Println("错误: 连接数据库失败: " + err.Error())
	}

	// 测试连接
	if err := newDB.Ping(); err != nil {
		newDB.Close()
		db.DB = newDB
	}
	db.DB = newDB
	return nil
}

// 执行SQL语句函数
func (db *Database) executeQuery(args ...object.Object) object.Object {
	if len(args) != 2 {
		fmt.Println("错误: execute() 函数需要两个参数: 数据库连接和SQL语句")
	}

	sqlStmt, ok := args[0].(*object.String)
	if !ok {
		// return object.NewError("argument to get() must be a string")
	}

	result, err := db.DB.Exec(sqlStmt.Value)
	if err != nil {
		fmt.Println("错误: 执行SQL失败: " + err.Error())
	}

	rowsAffected, err := result.RowsAffected()
	if err != nil {
		fmt.Println("错误: 获取受影响的行数失败: " + err.Error())
	}

	return &object.Integer{Value: rowsAffected}
}

// 查询数据库函数
func (db *Database) queryDB(args ...object.Object) object.Object {
	sqlStmt, ok := args[0].(*object.String)
	if !ok {
		// return object.NewError("argument to get() must be a string")
	}

	/* sqlStmt, ok := args[1].(String)
	if !ok {
		fmt.Println("错误: 第二个参数必须是字符串类型")
	} */

	rows, err := db.DB.Query(sqlStmt.Value)
	if err != nil {
		fmt.Println("错误: 执行查询失败: " + err.Error())
	}

	columns, err := rows.Columns()
	if err != nil {
		rows.Close()
		fmt.Println("错误: 获取列信息失败: " + err.Error())
	}
	fmt.Println("查询结果列:", rows)
	fmt.Println("查询结果列:", columns)
	// return &ResultSet{Rows: rows, Columns: columns}
	return nil
}

// SqlitModule 实现Module接口
type SqliteModule struct{}

// Name 返回模块名称
func (m *SqliteModule) Name() string {
	return "sqlite"
}

// Methods 返回模块方法
func (m *SqliteModule) Methods() map[string]object.NativeFunction {
	db := NewDatabase()
	return map[string]object.NativeFunction{
		"connect": db.connectDB,
		"query":   db.queryDB,
		"execute": db.executeQuery,
	}
}
